Skip to content

fix(aws): harden CloudFormation BYOC releases#179

Open
alongubkin wants to merge 13 commits into
mainfrom
alon/alien-320-harden-aws-cloudformation-byoc-release-path
Open

fix(aws): harden CloudFormation BYOC releases#179
alongubkin wants to merge 13 commits into
mainfrom
alon/alien-320-harden-aws-cloudformation-byoc-release-path

Conversation

@alongubkin

@alongubkin alongubkin commented Jul 23, 2026

Copy link
Copy Markdown
Member

Summary

  • emit valid NextGen OpenSearch Serverless and storage CORS CloudFormation resources
  • preserve deployer input values and include transitive native-addon bytes in build cache keys
  • avoid unauthenticated bootstrap OTLP export when runtime secrets are vault-backed
  • parse raw storage keys before signing so reserved characters are encoded exactly once

Validation

  • focused OpenSearch and storage CloudFormation generator tests
  • AWS CloudFormation ValidateTemplate and real create/update deployment proof
  • real AWS NextGen collection-group deployment: Generation: NEXTGEN, zero minimum indexing/search OCU, on.aws endpoint
  • full locally built application proof through Platform pnpm dev: TLS/health, send, asynchronous indexing, full-text search hit, and content retrieval
  • focused native storage-path and transitive-cache tests
  • focused worker-runtime OTLP test plus deployed cold-start/export proof
  • cargo check --locked -p alien-bindings-node

Linear: ALIEN-320

@greptile-apps

greptile-apps Bot commented Jul 23, 2026

Copy link
Copy Markdown

Greptile Summary

This PR hardens AWS CloudFormation BYOC (Bring Your Own Cloud) release generation across four distinct areas, each with focused tests and real deployment proof.

  • SES inbound email automation: Replaces the previous manual "activate rule set" post-deploy step with a stack-local CloudFormation custom resource (Lambda + IAM role) that activates the provisioned AWS::SES::ReceiptRuleSet on create/update and safely deactivates it on delete only if it is still the currently-active rule set. A new topology validator rejects stacks with more than one inbound email resource at generation time.
  • OpenSearch Serverless capacity limits: Extends the AwsOpenSearch resource with optional capacity (indexing/search OCU bounds) validated against AWS's supported increment set, emitted as CapacityLimits on the NEXTGEN collection group.
  • Storage CORS & path parsing: Emits a CorsConfiguration rule on S3 buckets when corsAllowedOrigins is set; switches all storage binding calls from Path::from (no validation) to Path::parse (rejects empty segments, preserves RFC characters exactly once before signing).
  • Runtime hardening: Defers OTLP bootstrap when ALIEN_RUNTIME_SECRETS indicates vault-backed credentials; replaces oneshot/Notify readiness primitives in ControlGrpcServer with watch channels so multiple concurrent waiters are correctly unblocked; propagates --input flag values to the platform API (previously HashMap::new() was always sent); includes transitive @alienplatform/bindings bytes in TypeScript build cache keys.

Confidence Score: 5/5

Safe to merge — all changes are additive fixes or hardening with real deployment and unit-test proof; no regressions observed.

The PR fixes three distinct correctness bugs (input values silently dropped, unauthenticated OTLP export before vault load, multiple waiters on a oneshot channel), adds tested new capabilities (CORS, OCU capacity limits, SES custom resource), and validates each through both focused unit tests and live AWS deployments. The most significant logic addition — the CloudFormation SES activation Lambda — handles the edge cases (no active rule set, in-place vs. replacement update, stack-managed vs. externally-managed rule sets) correctly. Code is well-commented and changes are well-scoped.

crates/alien-cloudformation/src/emitters/aws/email.rs (new custom resource Lambda — review Python inline code and IAM permissions carefully) and crates/alien-build/src/lib.rs (bindings_realpath overwrite edge case in hoisted-dependency layouts).

Important Files Changed

Filename Overview
crates/alien-cloudformation/src/emitters/aws/email.rs Adds a CloudFormation custom resource (Lambda + IAM role) that auto-activates the SES receipt rule set on deploy and safely deactivates it on delete; adds a topology validator rejecting multiple inbound email resources.
crates/alien-cloudformation/src/emitters/aws/storage.rs Emits CorsConfiguration on S3 buckets when corsAllowedOrigins is non-empty, with hardcoded GET/HEAD allowed methods, wildcard AllowedHeaders, ETag exposure, and 1-hour MaxAge.
crates/alien-cloudformation/src/emitters/aws/open_search.rs Calls validate_capacity() and conditionally emits CapacityLimits on the NEXTGEN collection group; new capacity_limits() helper maps indexing/search OCU values to the correct CloudFormation property names.
crates/alien-worker-protocol/src/control_service.rs Replaces oneshot/Notify readiness primitives with watch channels so multiple concurrent waiters on HTTP-server or task-subscriber readiness are all unblocked correctly; adds tests for the multi-waiter case.
crates/alien-worker-runtime/src/otlp.rs Adds vault-backed credential guard: when ALIEN_RUNTIME_SECRETS is present, init_otlp_logging() returns None (deferred) so no unauthenticated provider is installed; authenticated init happens later via init_otlp_logging_from_config.
crates/alien-worker-runtime/src/transports/lambda.rs Unifies buffered and streaming S3/SQS task conversion through shared s3_record_to_task/sqs_record_to_task helpers; adds drive_lambda_runtime() to deduplicate runtime + extension startup; uses new TaskDeliveryFailed error variant.
crates/alien-cli/src/commands/deploy.rs Fixes a silent bug where --input/--secret-input values were collected but an empty HashMap was sent to the platform API; adds parse_raw_stack_input_value and to_sdk_stack_input_values to correctly map JSON-typed values to the API's union type.
crates/alien-bindings-node/src/storage.rs Replaces Path::from (no validation) with Path::parse across all storage binding operations; returns a structured INVALID_INPUT error on bad paths, preserving RFC Message-ID characters while rejecting empty segments.
crates/alien-build/src/lib.rs Includes transitive @alienplatform/bindings bytes (reached via the sdk package) in the TypeScript build cache key; adds bindings_realpath override for the sdk case.
crates/alien-core/src/resources/aws_open_search.rs Adds AwsOpenSearchCapacity and AwsOpenSearchCapacityRange structs with validate_capacity() checking AWS's supported OCU increment set and min≤max ordering.

Sequence Diagram

sequenceDiagram
    participant main as main.rs
    participant runtime as runtime::run()
    participant otlp as otlp.rs
    participant vault as BindingsProvider (vault)
    participant lambda as LambdaTransport

    main->>otlp: init_otlp_logging()
    alt ALIEN_RUNTIME_SECRETS present (vault-backed)
        otlp-->>main: Ok(None) — deferred
    else env-only credentials
        otlp-->>main: Ok(Some(bridge)) — initialized
    end

    main->>runtime: run(config, deps)
    runtime->>lambda: prestart_lambda_transport() [Init phase]
    lambda-->>runtime: PrestartedTransport handle

    runtime->>vault: load_runtime_secrets()
    vault-->>runtime: "HashMap { OTEL_EXPORTER_OTLP_HEADERS: ... }"

    runtime->>otlp: init_otlp_logging_from_config(otlp_config)
    Note over otlp: Authenticated OTLP provider installed into OTLP_PROVIDER

    runtime->>runtime: start_application(child, log_exporter)

    Note over lambda: Invocation loop begins (wait_for_task_readiness per call)

    runtime->>runtime: run_transport() — joins prestarted handle
Loading

Reviews (4): Last reviewed commit: "fix: activate SES receipt rule sets duri..." | Re-trigger Greptile

export const StorageSchema = z.object({
"id": z.string().describe("Name of the the storage bucket.\nFor names with dots, each dot-separated label must be ≤ 63 characters."),
"corsAllowedOrigins": z.optional(z.array(z.string()).describe("Browser origins allowed to read objects through signed URLs.\n\nWhen non-empty, providers configure CORS for `GET` and `HEAD` requests.\nAn origin of `*` is appropriate for private buckets whose signed URLs\nare bearer credentials and do not use browser cookies.\nDefault: `[]` (CORS disabled).")),
"id": z.string().describe("Name of the the storage bucket.\nFor names with dots, each dot-separated label must be ≤ 63 characters."),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Generated file drops indentation for id field

The newly added corsAllowedOrigins property is indented (4 spaces) but "id" and the remaining pre-existing properties ("publicRead", "versioning") have zero indentation. This is a generator artifact: the tool appears to emit consistent indentation only for the first alphabetical property. TypeScript and Zod parse the file correctly, so this has no runtime impact, but it points to an inconsistency in the code generator that may resurface as the schema grows.

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/core/src/generated/zod/storage-schema.ts
Line: 14

Comment:
**Generated file drops indentation for `id` field**

The newly added `corsAllowedOrigins` property is indented (4 spaces) but `"id"` and the remaining pre-existing properties (`"publicRead"`, `"versioning"`) have zero indentation. This is a generator artifact: the tool appears to emit consistent indentation only for the first alphabetical property. TypeScript and Zod parse the file correctly, so this has no runtime impact, but it points to an inconsistency in the code generator that may resurface as the schema grows.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@alongubkin
alongubkin force-pushed the alon/alien-320-harden-aws-cloudformation-byoc-release-path branch 2 times, most recently from f9e9801 to d0e58d7 Compare July 23, 2026 02:18
@alongubkin
alongubkin force-pushed the alon/alien-320-harden-aws-cloudformation-byoc-release-path branch from d0e58d7 to b1d404a Compare July 23, 2026 02:31
@alongubkin

Copy link
Copy Markdown
Member Author

Final AWS validation update:

  • Live OpenSearch Serverless rejected 1 OCU for both indexing and search; the supported nonzero floor is 2. Validation/schema and the CloudFormation fixture now enforce that before deployment (4229ed78, 3a45a908).
  • The generated CloudFormation setup path updated a real NEXTGEN collection group to min indexing/search 2.0 OCU; the stack reached UPDATE_COMPLETE. The runtime manager correctly refused to mutate the frozen setup-owned capacity.
  • Real Lambda testing exposed that an 8-second pre-poll readiness budget could still cross Lambda’s 10-second init limit. 22c1bcc3 now polls the Runtime API immediately and keeps readiness waiting inside invocation handling. A cold API invocation had one init (1334.03 ms), HTTP 200, and no init timeout/restart.
  • A cold events invocation initialized once (1165.78 ms) and a deliberately unmatched valid SQS event returned FunctionError: Unhandled / TASK_DELIVERY_FAILED, proving failures are no longer silently acknowledged.
  • Focused results: OpenSearch core 8/8, CloudFormation generator 7/7, TypeScript core 67/67, AWS runtime 80/80. Fresh CI is running on 3a45a908.

@alongubkin

Copy link
Copy Markdown
Member Author

@greptileai

@alongubkin

Copy link
Copy Markdown
Member Author

@greptileai

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant